export default class DB {
	constructor(dbName) {
		this.dbName = dbName;
		this.dbPath = `_doc/${this.dbName}.db`;
		this.db = null;
		this.isOpenDb = false;
	}

	static init(dbName) {
		return new this(dbName);
	}

	initDB(curDbVer, masterTableName, createTableSqlArray, alterTableSqlArray) {
		return new Promise(async (a, b) => {
			try {
				
				await this.openDb();
				let ret = await this.selectSql("select count(*) as count from sqlite_master  where name='" + masterTableName +
					"'");
				if (ret[0].count == 0) { //如果表不存在
					//创建表
					if (createTableSqlArray && createTableSqlArray.length > 0) {
						for (let i = 0; i < createTableSqlArray.length; i++) {
							await this.executeSql(createTableSqlArray[i]);
						}
					}
					await this.executeSql('PRAGMA user_version=' + curDbVer);
				}

				//修改表
				if (alterTableSqlArray && alterTableSqlArray.length > 0) {
					let _ret = await this.selectSql('PRAGMA user_version');
					if (_ret[0].user_version !== curDbVer) {
						for (let i = 0; i < alterTableSqlArray.length; i++) {
							await this.executeSql(alterTableSqlArray[i]);
						}
						await this.executeSql('PRAGMA user_version=' + curDbVer);
					}
				}
				a();
			} catch (e) {
				b(e);
			}
		})
	}

	/**
	 * 打开数据库
	 */
	openDb() {
		return new Promise((a, b) => {
			//#ifdef APP-PLUS || APP-PLUS-NVUE
			plus.sqlite.openDatabase({
				name: this.dbName,
				path: this.dbPath,
				success() {
					a();
				},
				fail(e) {
					console.log('数据库打开失败，数据库名称:' + this.dbName + ',错误信息: ' + JSON.stringify(e));
					b(e);
				}
			});
			//#endif

			//#ifdef H5
			this.db = openDatabase(this.dbName, '1.0', '', 50 * 1024 * 1024);
			this.isOpenDb = true;
			a();
			//#endif

		})
	}

	/**
	 * 关闭数据库
	 */
	closeDb() {
		//#ifdef APP-PLUS || APP-PLUS-NVUE
		// return new Promise((a, b) => {
		// 	plus.sqlite.closeDatabase({
		// 		name: this.dbName,
		// 		success() {
		// 			a();
		// 		},
		// 		fail(e) {
		// 			console.log('数据库关闭失败，数据库名称:' + this.dbName + ',错误信息: ' + JSON.stringify(e));
		// 			b(e);
		// 		}
		// 	});
		// })
		//#endif
	}


	/**
	 * 数据库是否打开
	 */
	isOpen() {
		//#ifdef APP-PLUS || APP-PLUS-NVUE
		return plus.sqlite.isOpenDatabase({
			name: this.dbName,
			path: this.dbPath
		});
		//#endif
		return this.isOpenDb;
		//#ifdef H5
		return true;
		//#endif
	}

	/**
	 * 执行事务
	 * @param {String} operation 可选值：begin（开始事务）、commit（提交）、rollback（回滚）
	 */
	transaction(operation) {
		return new Promise(async (a, b) => {
			if (!this.isOpen()) {
				await this.openDb();
			}
			plus.sqlite.transaction({
				name: this.dbName,
				operation: operation,
				success: async function(data) {
					await this.closeDb();
					a(data);
				}.bind(this),
				fail: async function(e) {
					await this.closeDb();
					console.log('事务执行失败，错误信息: ' + JSON.stringify(e));
					b(e);
				}.bind(this)
			});
		})
	}

	/**
	 * 执行sql语句，除查询外的语句
	 * @param {Array|String} sql
	 */
	executeSql(sql) {
		return new Promise(async (a, b) => {
			if (!this.isOpen()) {
				await this.openDb();
			}
			//#ifdef APP-PLUS || APP-PLUS-NVUE
			plus.sqlite.executeSql({
				name: this.dbName,
				sql: sql,
				success: async function(data) {
					await this.closeDb();
					a(data);
				}.bind(this),
				fail: async function(e) {
					await this.closeDb();
					console.log('SQL语句执行失败, ' + sql + ' ,错误信息: ' + JSON.stringify(e));
					b(e);
				}.bind(this)
			});
			//#endif

			//#ifdef H5
			
			this.db.transaction((tx)=> {
				if(sql instanceof Array){
					sql.forEach((item)=>{
						tx.executeSql(item, [], (tx, ret)=> {
							a(ret);
						});
					})
				}else{
				
					tx.executeSql(sql, [], (tx, ret)=> {
						console.log(sql,ret)
						a(ret);
					});
				}
			});
		
			//#endif

		})
	}

	/**
	 * 查询SQL
	 * @param {String} sql
	 */
	selectSql(sql) {
		return new Promise(async (a, b) => {
			if (!this.isOpen()) {
				await this.openDb();
			}
			//#ifdef APP-PLUS || APP-PLUS-NVUE
			plus.sqlite.selectSql({
				name: this.dbName,
				sql: sql,
				success: async function(data) {
					
					await this.closeDb();
					a(data);
				}.bind(this),
				fail: async function(e) {
					await this.closeDb();
					console.log('SQL语句查询失败, ' + sql + ' ,错误信息: ' + JSON.stringify(e));
					b(e);
				}.bind(this)
			});
			//#endif

			//#ifdef H5
			this.db.transaction((tx)=> {
				tx.executeSql(sql, [], (tx, ret)=> {
					let rows=[];
					
					if(typeof ret.rows == "object"){
						for(let index in ret.rows){
							if(index && !isNaN(index) && ret.rows[index]){
								rows.push(ret.rows[index]);
							}
						}
					}
					
					a(rows);
				});
			});
			//#endif

		})
	}


}
